.file "fib_rv64.s"

.option nopic
.attribute arch, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0"
.attribute unaligned_access, 0
.attribute stack_align, 16

# ==================== 数据段 ====================
.section .data
.align 2
a:
    .word 0
b:
    .word 1

# 全局计数器，统计奇数个数
globalCounter:
    .word 0

# ==================== 只读数据段 ====================
.section .rodata.str1.8,"aMS",@progbits,1
.align 3
.LC0:
    .string "%d"
.LC1:
    .string "%d\n"
.LC2:
    .string "Fib: %d, Odd: %d\n"  # 格式化输出：斐波那契值和是否为奇数

# ==================== 代码段 ====================
.section .text.startup,"ax",@progbits
.align 1
.globl main
.type main, @function

main:
    addi sp, sp, -32
    sd   s0, 16(sp)
    sd   s1, 8(sp)
    sd   ra, 24(sp)

    # 读取 n
    lui  s0, %hi(n)
    lui  a0, %hi(.LC0)
    addi a1, s0, %lo(n)
    addi a0, a0, %lo(.LC0)
    call __isoc99_scanf

    # 初始化 globalCounter = 0
    lui  t0, %hi(globalCounter)
    li   t1, 0
    sw   t1, %lo(globalCounter)(t0)

    # 加载 a, b, n
    lui  s2, %hi(a)
    lw   s1, %lo(a)(s2)       # s1 = a
    lui  s3, %hi(b)
    lw   s2, %lo(b)(s3)       # s2 = b
    lui  s4, %hi(n)
    lw   s4, %lo(n)(s4)       # s4 = n
    li   s0, 0                # s0 = i = 0 (循环计数器)

.L1:  # 循环开始：输出前 n 个斐波那契数
    mv   a0, s1               # 将当前斐波那契数传给 a0
    call isOdd                # 调用 isOdd，返回值在 a0

    # 保存 isOdd 的返回值
    mv   s5, a0

    # 准备 printf 参数
    lui  a0, %hi(.LC2)
    addi a0, a0, %lo(.LC2)
    mv   a1, s1               # a1 = fibValue
    mv   a2, s5               # a2 = isOdd 的结果
    call printf

    # 更新斐波那契数列：next = a + b; a = b; b = next
    add  t0, s1, s2           # t0 = s1 + s2
    mv   s1, s2               # s1 = b
    mv   s2, t0               # s2 = a + b

    addi s0, s0, 1            # i++
    blt  s0, s4, .L1          # if i < n, continue

    # 恢复寄存器
    ld   ra, 24(sp)
    ld   s0, 16(sp)
    ld   s1, 8(sp)
    addi sp, sp, 32
    li   a0, 0                # 返回 0
    jr   ra

.size main, .-main

# ==================== isOdd 函数 ====================
.globl isOdd
.type isOdd, @function
isOdd:
    addi sp, sp, -16
    sd   s0, 8(sp)            # 保存 s0
    sd   ra, 0(sp)            # 保存 ra

    mv   s0, a0               # 从 a0 读取参数 num

    andi t0, s0, 1            # t0 = num & 1
    bne  t0, zero, .is_odd    # 如果为 1，则是奇数

    # 偶数：返回 0
    li   a0, 0
    j    .isOdd_end

.is_odd:
    # 奇数：globalCounter++
    lui  t1, %hi(globalCounter)
    lw   t2, %lo(globalCounter)(t1)
    addi t2, t2, 1
    sw   t2, %lo(globalCounter)(t1)
    li   a0, 1                # 返回 1

.isOdd_end:
    ld   ra, 0(sp)            # 恢复 ra
    ld   s0, 8(sp)            # 恢复 s0
    addi sp, sp, 16
    jr   ra

.size isOdd, .-isOdd

# ==================== 全局变量 n ====================
.globl n
.section .sbss,"aw",@nobits
.align 2
.type n, @object
.size n, 4
n:
    .zero 4

# ==================== 其他 ====================
.ident "GCC: (GNU) 12.2.0"
.section .note.GNU-stack,"",@progbits